#include <stdio.h>
#include <stddef.h>
#include <string.h>
#include <stdlib.h>
#include "Sc2sim.h"

#define ushort unsigned short

int main(int argc, char * argv[]) {
	short running = 1;
	short needMenu = 0;
	FILE * file = NULL;//have to be careful about this
	CPU cpu = cpu_initialize();
	Memory mem = mem_intialize();
	while (running) {
		if(argc > 1 && strcmp(argv[1], "-p") == 0 && needMenu == 0) {	
			file = fopen(argv[1], "r");
			if(file == NULL) {
				printf("File specified in command line was not found!");
				needMenu = 1;
			}
			else if(argc > 2 && strcmp(argv[2], "-s") == 0) {
				step();
				needMenu = 1;
			}
		}
		else
			file = displayMenu(cpu, mem, file);
	}
}

FILE * displayMenu(CPU cpu, Memory mem, FILE * file) {
	printf("Select: 1) Load File, 2) Run, 3) Step, 4) Display Registers, 5) Display Memory, 6) Quit");
	char temp[2];
	int error = 0;
	int * err = &error;
	scanf("%1s", temp);
	temp[1] = '/0';
	int tempint = atoi(temp);
	switch(tempint) {
		case 1:
			file = load(cpu, mem, file);
			break;
		case 2:
			run();
			break;
		case 3:
			step();
			break;
		case 4: 
			display_registerFile(cpu->reg_file);
			break;
		case 5:
			//CHANGE THIS
			display_memoryBlock(mem, 0x3000, 0x3000 + 16, err);
			break;
		case 6:
			exit(0);
		default:
			printf("Incorrect selection. Please try again.");
			displayMenu(cpu, mem, file);
			break;
	}
	return file;
}

FILE * load(CPU cpu, Memory mem) {
	char * temp = (char *) malloc(sizeof(char) * 26);
	printf("Please enter a file name (maximum 25 characters): ");
	scanf("%25s", temp);
	temp[25] = '/0';
	FILE * file = fopen(temp, "r");
	if (file != NULL) 
		loadMem(cpu, mem, file);
	else
		printf("Specified file not found!");
	return file;
}

void run(CPU cpu, Memory mem) {
	int halt = 0;
	while(halt == 0)
		halt = cpu_tick(cpu, mem);
	printf("Halt bit was set and the program ended.");
}

void step(CPU cpu, Memory mem) {
	cpu_tick(cpu, mem);
}

ushort nextInstruction(FILE * file) {
	if(file == NULL || feof(file)) return 0;
	char * line1 = (char *) malloc(sizeof(char) * 4);//char * 4 because fgets includes newline
	fgets(line1, 4, file);
	int i = 0;
	for(i, i < 3; i++) {
		if (strcmp(line1[i], '/n' == 0))
			line1[i] == '/0'; //get rid of newline for safety
	}
	char * line2 = (char *) malloc(sizeof(char) * 4);
	fgets(line2, 3, file);
	i = 0;
	for (i, i < 3; i++) {
		if (strcmp(line2[i], '/n' == 0))
			line2[i] = '/0'
	}
	char * line = (char *) malloc(sizeof(char) * 5);//4 chars(one hex word) and a null terminator
	i = 0;
	int j = 0;
	//line 2 is high order byte, line 1 is low order byte
	for(i; i < 4; i++) {
		if(i < 2)
			line[i] = line2[i];
		else {
			line[i] = line1[j];
			j++;
		}
	}
	line[4] = "/0";
	char * end = (char *) malloc(sizeof(char));
	char ** endptr = &end;
	ushort result = (ushort)strtoul(line, endptr, 16);
	return result;
}

ushort loadMem(CPU cpu, Memory mem, FILE * file) {
	ushort returnval = 0;
	if(cpu != NULL && mem != NULL && file != NULL) {
		int count = 0x3000;
		int err = 0;
		for(count; count < MEM_LAST; count+2) {
			err = memory_putWordTo(mem, count, nextInstruction(file));
			if(err) {
				printf("Error while loading program to memory, skipping.");
				break;
			}
		}
		if(!err)
			returnval = 1;
	}
	return returnval;
}
